package com.iteaj.iot.client.http;

import com.iteaj.iot.client.ClientMessage;
import okhttp3.FormBody;
import okhttp3.RequestBody;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class HttpClientMessage extends ClientMessage {

    private String url;

    /**
     * http使用的方法, 只支持两种
     * @see HttpMethod#Get
     * @see HttpMethod#Post
     */
    private HttpMethod method;

    /**
     * http请求的请求头
     */
    private Map<String, String> heads;
    /**
     * 请求参数, url的?xxx部分
     */
    private Map<String, Object> queryParam;

    /**
     * 请求body
     */
    private RequestBody requestBody;

    /**
     * 标准http协议状态码
     */
    private int code;

    /**
     * 响应报文
     */
    private String content;

    /**
     * 响应报文的 contentType
     */
    private String contentType;

    /**
     * 响应状态
     */
    private String statusMsg;

    /**
     * 异常信息
     */
    private Exception exception;

    public HttpClientMessage() {
        super(EMPTY);
    }

    public HttpClientMessage(String url, HttpMethod method) {
        this(url, method, null);
    }

    public HttpClientMessage(String url, HttpMethod method, Map<String, Object> queryParam) {
        super(new byte[]{0});
        this.url = url;
        this.method = method;
        this.queryParam = queryParam;
    }

    public HttpClientMessage(String url, Map<String, Object> queryParam, Map<String, String> formBody) {
        super(new byte[]{0});
        this.url = url;
        this.method = HttpMethod.Post;
        this.queryParam = queryParam;
        FormBody.Builder builder = new FormBody.Builder();
        if(formBody != null) {
            formBody.forEach((key, value) -> {
                builder.add(key, value);
            });
        }
        this.requestBody = builder.build();
    }

    public HttpClientMessage(String url, Map<String, Object> queryParam, RequestBody requestBody) {
        super(new byte[]{0});
        this.url = url;
        this.method = HttpMethod.Post;
        this.queryParam = queryParam;
        this.requestBody = requestBody;
    }

    /**
     * 响应构建
     * @param code
     * @param content
     * @return
     */
    public HttpClientMessage build(int code, String content) {
        return this.build(code, content, null, null);
    }

    /**
     * 响应构建
     * @param code
     * @param message
     * @param contentType
     * @param statusMsg
     * @return
     */
    public HttpClientMessage build(int code, String message, String contentType, String statusMsg) {
        this.code = code;
        this.statusMsg = statusMsg;
        this.content = message;
        this.contentType = contentType;
        return this;
    }

    /**
     * 响应构建
     * @param exception
     * @return
     */
    public HttpClientMessage build(Exception exception) {
        this.code = 500;
        this.exception = exception;
        return this;
    }

    public String getContent() {
        return this.content;
    }

    @Override
    public int length() {
        return content != null ? content.length() : 0;
    }

    /**
     * 响应报文
     * @return
     */
    @Override
    public byte[] getMessage() {
        return content.getBytes(StandardCharsets.UTF_8);
    }

    public boolean isOK() {
        if(cause() != null) {
            return false;
        }

        return code == 200;
    }

    @Override
    public MessageHead getHead() {
        throw new UnsupportedOperationException("不支持的操作");
    }

    @Override
    public MessageBody getBody() {
        throw new UnsupportedOperationException("不支持的操作");
    }

    public HttpMethod getMethod() {
        return method;
    }

    public Map<String, Object> getQueryParam() {
        return queryParam;
    }

    public HttpClientMessage addParam(String key, String value) {
        if(this.queryParam == null) {
            this.queryParam = new HashMap<>();
        }

        this.queryParam.put(key, value);
        return this;
    }

    public Map<String, String> getHeads() {
        return heads;
    }

    public HttpClientMessage addHeader(String key, String val) {
        if(this.heads == null) {
            this.heads = new HashMap<>();
        }

        this.heads.put(key, val);
        return this;
    }

    public HttpClientMessage setHeads(Map<String, String> heads) {
        this.heads = heads;
        return this;
    }

    public String getUrl() {
        return url;
    }

    public HttpClientMessage setUrl(String url) {
        this.url = url;
        return this;
    }

    public RequestBody getRequestBody() {
        return requestBody;
    }

    public HttpClientMessage setRequestBody(RequestBody requestBody) {
        this.requestBody = requestBody; return this;
    }

    public int getCode() {
        return code;
    }

    public String getContentType() {
        return contentType;
    }

    public String getStatusMsg() {
        return statusMsg;
    }

    public Exception cause() {
        return exception;
    }

    @Override
    protected MessageHead doBuild(byte[] message) {
        throw new UnsupportedOperationException("不支持此操作");
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();

        if(getCode() != 0 || cause() != null) {
            if(cause() != null) {
                sb.append(cause().getMessage());
            } else {
                sb.append(this.getContent());
            }
        } else {
            sb.append("method=").append(method);
            if(queryParam != null) {
                queryParam.forEach((key, value) -> {
                    sb.append(key).append('=').append(value).append(',');
                });
            }
        }
        return sb.toString();
    }
}
